package myapp.googlemap;

import java.util.ArrayList;
import java.util.List;

import myapp.DTO.CategoryDTO;
import myapp.DTO.ServiceDTO;
import myapp.DTO.UserDTO;
import myapp.EnumAndConstans.Constants;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.text.Html;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.Surface;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import myapp.camera.MainActivity;
import myapp.database.*;
import myapp.dictionary.MyDictionary;
import myapp.helper.NetworkHelper;
import myapp.helper.OrientationHelper;
import myapp.helper.Utils;
import myapp.kalman_filter.KalmanState;
import myapp.services.ChatServiceHelper;

public class GoogleMapActivity extends MapActivity {
    static final int ZOOM_INDEX = 18;
    private final int optionsItemSelected_GetDirection = Menu.FIRST;
	//Compass
	Boolean isCompass = true;
	Boolean changeIntent = true;
	float[] aValues = new float[3];
	float[] mValues = new float[3];
	SensorManager sensorManager;
	KalmanState kmYaw;
	KalmanState kmPitch;
	KalmanState kmRoll;
	//Compass//////////////
    
    private CategoryDB categoryDB;
    private ItemDB itemDB;
    ArrayList<ServiceDTO> service_data_original;
    ArrayList<ServiceDTO> service_data;
	ArrayList<CategoryDTO> category_data;
	
    
	private MapController mapController;
	private List<Overlay> mapOverlays;
	private IconTextDrawable drawable;
	private static MapView mapView;
	private MyLocationOverlay myLocationOverlay=null; //Show google compass

	
//	private Location curLocation = null;
	
	Button button_OK_Change_Your_Location;
	Button button_OK_Driving_Directions;
	Button button_Get_Directions;
	
	boolean bool_autoUpdateLocation = true;

	int category = 0;
	int distance_max = 100;
	int distance_min = 0;

	int state_of_googlemap;
	static String directions_message = "";
	String startAddress;
	String endAddress;

	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);             
                
        setContentView(R.layout.activity_google_map);
        

        
		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);;
        bool_autoUpdateLocation = prefs.getBoolean(Constants.autoUpdateLocation, true);

        //Compass
    	if (isCompass == true)
    	{
    		sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);     
   
		    kmYaw = new KalmanState(1, 5, 2, 0); //Loc Kalman
		    kmPitch = new KalmanState(1, 5, 2, 0); //Loc Kalman
		    kmRoll = new KalmanState(1, 5, 2, 0); //Loc Kalman
		    
		    updateOrientation(new float[] {0, 0, 0});
    	}
        //Compass//////////////
        
        mapView = (MapView)findViewById(R.id.mapview);
        mapView.setBuiltInZoomControls(true);
        
        //------------------------------
//        mapView.setStreetView(true);
        mapController = mapView.getController();
        mapController.setZoom(ZOOM_INDEX);
        
        //Add google compass
        myLocationOverlay = new MyLocationOverlay(this, mapView);
        mapView.getOverlays().add(myLocationOverlay);
        
        LocationManager locationManager = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
      
        mapOverlays = mapView.getOverlays();
        
        drawable = new IconTextDrawable(this, R.drawable.hand_point_icon, "You are here");//this.getResources().getDrawable(R.drawable.hand_point_icon);
        
        if (bool_autoUpdateLocation == true)
        {
	        Criteria criteria = new Criteria();
	        criteria.setAccuracy(Criteria.ACCURACY_FINE);
	        criteria.setAltitudeRequired(false);
	        criteria.setBearingRequired(false);
	        criteria.setCostAllowed(true);
	        criteria.setPowerRequirement(Criteria.POWER_LOW);
	        String bestProvider = locationManager.getBestProvider(criteria, true);
	        
	        locationManager.requestLocationUpdates(bestProvider, 1,
					1, new GeoUpdateHandler(this));
	        
	        Location location = null;       
	    	
	        try {//LocationManager.NETWORK_PROVIDER
	        	location = locationManager.getLastKnownLocation(bestProvider);//locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
	        } catch (Exception e) {
				// TODO: handle exception
				AlertDialog.Builder dialog = new AlertDialog.Builder(this);
	    		dialog.setTitle("Get first error");
	    		dialog.setMessage(e.getMessage());
	    		dialog.show();
			}
	        
	        if (location == null){
	        	AlertDialog.Builder dialog = new AlertDialog.Builder(this);
	    		dialog.setTitle("Location error");
	    		dialog.setMessage("Get first location failed. Set default location!");
	    		dialog.show();
	    		SetYourFirstPosition((int)(OrientationHelper.getCurLat()*1E6), (int)(OrientationHelper.getCurLon()*1E6));
	        }
	        else{
	 //       	curLocation = location;
	        	SetYourFirstPosition(location);
	        } 
        }
        else
        	SetYourFirstPosition(OrientationHelper.getCurLat(), OrientationHelper.getCurLon());
        	
        state_of_googlemap = (int) getIntent().getExtras().getInt("state_of_googlemap", 1);
        switch (state_of_googlemap) {
		case Constants.STATE_GOOGLEMAP_DISPLAY_ONE_SERVICE:
		{
			changeIntent = false;
			try
	        {
	        	int itemLat = 10768134;
	        	int itemLong =  106693988;
	        	final ServiceDTO serviceItem =  (ServiceDTO) getIntent().getExtras().get("serviceItem");
	        	
	        	Log.i("Google_service_Lat", String.valueOf(serviceItem.getLatitude()));
	        	Log.i("Google_service_Lat", String.valueOf(serviceItem.getLongitude()));
	        	
	        	itemLat = (int)(serviceItem.getLatitude()*1000000);
	        	itemLong = (int)(serviceItem.getLongitude()*1000000);

	        	IconTextDrawable _drawable = new IconTextDrawable(this, MyDictionary.dictionary.get(serviceItem.getCategoryId()), Utils.StringToMultiLineString(serviceItem.getName(), 25));
		        MyItemizedOverlay itemizedoverlay = new MyItemizedOverlay(_drawable, this);
		 	    GeoPoint point = new GeoPoint(itemLat, itemLong);
		 	    
		 	    String info = "";	
		 	    if (serviceItem.getAddress() != null)
		 	    	if (serviceItem.getAddress().length() != 0)
		 	    		info += Html.fromHtml("Address: " + serviceItem.getAddress()).toString();
		 	    if (serviceItem.getPhoneNumber() != null)
		 	    	if (serviceItem.getPhoneNumber().length() != 0)
		 	    		info += Html.fromHtml("<br/>Phone: " + serviceItem.getPhoneNumber()).toString();
		        OverlayItem overlayitem = new OverlayItem(point, serviceItem.getName(), info);
		        itemizedoverlay.addOverlay(overlayitem);
		        mapOverlays.add(itemizedoverlay);
		        
		        mapController.zoomToSpan(Math.abs((int)(OrientationHelper.getCurLat()*1E6) - itemLat), Math.abs((int)(OrientationHelper.getCurLon()*1E6)  - itemLong));
		        mapController.animateTo(new GeoPoint( 
		        		((int)(OrientationHelper.getCurLat()*1E6) + itemLat)/2, 
		        		((int)(OrientationHelper.getCurLon()*1E6) + itemLong)/2 ));
		        

		        if (NetworkHelper.isNetworkAvailable(GoogleMapActivity.this) == false)
		        {
	           		 AlertDialog.Builder dialog = new AlertDialog.Builder(GoogleMapActivity.this);
	        		 dialog.setTitle("No Internet Connection");
	        		 dialog.setMessage("You don't have internet connection.");
	        		 dialog.show();
		        }
		        else
		        {
			        new Thread() {
			        	@Override
			        	public void run() {
			        		try
			        		{
				        		Route route = directions(new GeoPoint((int)(OrientationHelper.getCurLat()*1E6),(int)(OrientationHelper.getCurLon()*1E6)),
				        				new GeoPoint((int)(serviceItem.getLatitude()*1E6),(int)(serviceItem.getLongitude()*1E6)));
				        		Log.i("Google_Parse_Route", route.getName());
				        		
				        		RouteOverlay routeOverlay = new RouteOverlay(route, Color.RED);			        		
				        		mapOverlays.add(routeOverlay);
	
				        		directions_message = "Khoảng cách: " + String.valueOf(route.getLength()) + "m\n \n";
				        		for (int i = 0; i < route.getSegments().size();i++)
				        		{
				        			directions_message += "Đoạn dài " + route.getSegments().get(i).getLength() + "m" + "\n";
				        			directions_message += route.getSegments().get(i).getInstruction() + "\n \n";		        			
				        		}
				        		sleep(100);
				        		
				        		mHandler.sendMessage(Message.obtain(mHandler,
				        				Constants.GOOGLEMAP_ACTIVITY_HANDLER_CODE_REFRESH_MAPVIEW));
			        		
			        		
			        		}
			        		catch (Exception e)
			        		{
			        			
			        		}
			        	}
	
	
			        }.start();
			        		        
		        }
	        }
	        catch (Exception ex)
	        {
	        }
	        
			

			break;
			
			
		}
		
		case Constants.STATE_GOOGLEMAP_SET_SERVICE_LOCATION:
		{
			changeIntent = false;
			GeoPoint point = new GeoPoint((int)(OrientationHelper.getCurLat()*1E6), (int)(OrientationHelper.getCurLon()*1E6));
			mapController.animateTo(point); 
			mapController.setCenter(point);
			MyItemizedOverlay my = (MyItemizedOverlay)mapOverlays.get(1);
			my.SetDragAndDrop(true);
			mapOverlays.set(1, my);
			Toast.makeText(this.getApplicationContext(), "Drag and drop the hand point to change service's location", Toast.LENGTH_LONG).show();

			 
	        button_OK_Change_Your_Location = (Button)findViewById(R.id.button_ok_change_your_location);
	        button_OK_Change_Your_Location.setOnClickListener(new OnClickListener() {
				
				@Override
				public void onClick(View v) {
					// TODO Auto-generated method stub
					MyItemizedOverlay myItemizedOverlay = (MyItemizedOverlay)mapOverlays.get(1);
					GeoPoint geoPoint = myItemizedOverlay.GetGeoPoint();
					
					double serviceLat = (double)geoPoint.getLatitudeE6()/1E6;
					double serviceLon = (double)geoPoint.getLongitudeE6()/1E6;


					Intent output = new Intent();
					output.putExtra("latitude_service", serviceLat);	
					output.putExtra("longitude_service", serviceLon);	
					setResult(RESULT_OK, output);
					finish();
				}
			});
	        button_OK_Change_Your_Location.setVisibility(View.VISIBLE);
			break;
		}
		
		case Constants.STATE_GOOGLEMAP_DISPLAY_LIST_SERVICE:
			changeIntent = true;
	        //Cap nhat danh sach dich vu
	        getListService();
	        button_OK_Change_Your_Location = (Button)findViewById(R.id.button_ok_change_your_location);
	        button_OK_Change_Your_Location.setOnClickListener(new OnClickListener() {
				
				@Override
				public void onClick(View v) {
					// TODO Auto-generated method stub
					MyItemizedOverlay myItemizedOverlay = (MyItemizedOverlay)mapOverlays.get(1);
					GeoPoint geoPoint = myItemizedOverlay.GetGeoPoint();
					Log.i("Google_handPoint_Lat", String.valueOf(geoPoint.getLatitudeE6()));
					Log.i("Google_handPoint_Lon", String.valueOf(geoPoint.getLongitudeE6()));
					
					OrientationHelper.setCurLatLon((double)geoPoint.getLatitudeE6()/1E6, (double)geoPoint.getLongitudeE6()/1E6);
					myItemizedOverlay.SetDragAndDrop(false);
					mapOverlays.set(1, myItemizedOverlay);
					button_OK_Change_Your_Location.setVisibility(View.INVISIBLE);
				}
			});
	        
	        button_OK_Driving_Directions = (Button)findViewById(R.id.button_ok_driving_directions);
	        button_OK_Driving_Directions.setOnClickListener(new OnClickListener() {
				
				@Override
				public void onClick(View v) {
					// TODO Auto-generated method stub
					MyItemizedOverlay a_myItemizedOverlay = (MyItemizedOverlay)mapOverlays.get(2);//Start point				
					MyItemizedOverlay b_myItemizedOverlay = (MyItemizedOverlay)mapOverlays.get(3);//End point
					
					a_myItemizedOverlay.SetDragAndDrop(false);
					b_myItemizedOverlay.SetDragAndDrop(false);
					
					mapOverlays.set(2, a_myItemizedOverlay);
					mapOverlays.set(3, b_myItemizedOverlay);
					
					
					final GeoPoint a_Point = a_myItemizedOverlay.GetGeoPoint();
					final GeoPoint b_Point = b_myItemizedOverlay.GetGeoPoint();
					
					try
					{
				        if (NetworkHelper.isNetworkAvailable(GoogleMapActivity.this) == false)
				        {
			           		 AlertDialog.Builder dialog = new AlertDialog.Builder(GoogleMapActivity.this);
			        		 dialog.setTitle("No Internet Connection");
			        		 dialog.setMessage("You don't have internet connection.");
			        		 dialog.show();
				        }
				        else
				        {
					        new Thread() {
					        	@Override
					        	public void run() {
					        		try
					        		{
						        		Route route = directions(a_Point, b_Point);
						        		Log.i("Google_Parse_Route", route.getName());
						        		startAddress = route.getStart();
						        		endAddress = route.getEnd();
						        		RouteOverlay routeOverlay = new RouteOverlay(route, Color.RED);			        		
						        		mapOverlays.add(routeOverlay);
			
						        		directions_message = "Khoảng cách: " + String.valueOf(route.getLength()) + "m\n \n";
						        		for (int i = 0; i < route.getSegments().size();i++)
						        		{
						        			directions_message += "Đoạn dài " + route.getSegments().get(i).getLength() + "m" + "\n";
						        			directions_message += route.getSegments().get(i).getInstruction() + "\n \n";		        			
						        		}
						        		sleep(100);
						        		
						        		mHandler.sendMessage(Message.obtain(mHandler,
						        				Constants.GOOGLEMAP_ACTIVITY_HANDLER_CODE_REFRESH_MAPVIEW_AND_SHOW_BUTTON_GET_DIRECTIONS));
					        		
					        		
					        		}
					        		catch (Exception e)
					        		{
					        			
					        		}
					        	}
			
			
					        }.start();
					        		        
				        }
			        }
			        catch (Exception ex)
			        {
			        }
					button_OK_Driving_Directions.setVisibility(View.INVISIBLE);

				}
			});
	        
	        button_Get_Directions = (Button)findViewById(R.id.button_get_directions);
	        button_Get_Directions.setOnClickListener(new OnClickListener() {
				
				@Override
				public void onClick(View v) {
					// TODO Auto-generated method stub
		    		 AlertDialog.Builder dialog = new AlertDialog.Builder(GoogleMapActivity.this);
		    		 dialog.setTitle("Directions");
		    		 dialog.setMessage(directions_message);
		    		 dialog.show();
				}
			});
	        
			break;
		default:
			break;
		}
    }

   
    private Route directions(final GeoPoint start, final GeoPoint dest) {
        Parser parser;
        //https://developers.google.com/maps/documentation/directions/#JSON <- get api
        String jsonURL = "http://maps.googleapis.com/maps/api/directions/json?";
        final StringBuffer sBuf = new StringBuffer(jsonURL);
        sBuf.append("origin=");
        sBuf.append(start.getLatitudeE6()/1E6);
        sBuf.append(',');
        sBuf.append(start.getLongitudeE6()/1E6);
        sBuf.append("&destination=");
        sBuf.append(dest.getLatitudeE6()/1E6);
        sBuf.append(',');
        sBuf.append(dest.getLongitudeE6()/1E6);
        sBuf.append("&sensor=true&mode=driving&language=vi");
        Log.i("Google_direction", sBuf.toString());
        parser = new GoogleParser(sBuf.toString());
        Route r =  parser.parse();
        return r;
    }
    
    
    private Handler mHandler=new Handler(){
    	@Override
    	public void handleMessage(Message message){
    		switch (message.what){
    		case Constants.GOOGLEMAP_ACTIVITY_HANDLER_CODE_REFRESH_MAPVIEW:
    		{
    			try
    			{
    				mapView.invalidate();
    			}
    			catch (Exception e)
    			{}
    			break;
    		}
    		case Constants.GOOGLEMAP_ACTIVITY_HANDLER_CODE_REFRESH_MAPVIEW_AND_SHOW_BUTTON_GET_DIRECTIONS:
    			try
    			{
    				button_Get_Directions.setVisibility(View.VISIBLE);
					MyItemizedOverlay a_myItemizedOverlay = (MyItemizedOverlay)mapOverlays.get(2);//Start point				
					MyItemizedOverlay b_myItemizedOverlay = (MyItemizedOverlay)mapOverlays.get(3);//End point
										
					a_myItemizedOverlay.UpdateListOverlayItem(0, new OverlayItem(a_myItemizedOverlay.getItem(0).getPoint(), "Start", startAddress));
					b_myItemizedOverlay.UpdateListOverlayItem(0, new OverlayItem(b_myItemizedOverlay.getItem(0).getPoint(), "End", endAddress));
    				mapView.invalidate();
    			}
    			catch (Exception e)
    			{}
    			break;
    		}
    	}
    };
    
   private void SetYourFirstPosition(Location _location){
	   int lat = (int) (_location.getLatitude() * 1E6);
       int lon = (int) (_location.getLongitude() * 1E6);
       
       OrientationHelper.setCurLatLon(_location.getLatitude(), _location.getLongitude());
       //------------------------------
       
       MyItemizedOverlay itemizedoverlay = new MyItemizedOverlay(drawable, this, (ImageView)findViewById(R.id.drag), false);
	   GeoPoint point = new GeoPoint(lat,lon);
       OverlayItem overlayitem = new OverlayItem(point, "Notify", "You're here!");
       itemizedoverlay.addOverlay(overlayitem);
       mapOverlays.clear();
       mapOverlays.add(0, myLocationOverlay);
       mapOverlays.add(1, itemizedoverlay);
       
       //Set focus for the map
       mapController.animateTo(point); 
       mapController.setCenter(point);
   }
   
   private void SetYourFirstPosition(double _lat, double _lon){       
       //------------------------------
       int lat = (int) (_lat*1E6);
       int lon = (int) (_lon*1E6);
       
	   
       MyItemizedOverlay itemizedoverlay = new MyItemizedOverlay(drawable, this, (ImageView)findViewById(R.id.drag), false);
	   GeoPoint point = new GeoPoint(lat, lon);
       OverlayItem overlayitem = new OverlayItem(point, "Notify", "You're here!");
       itemizedoverlay.addOverlay(overlayitem);
       mapOverlays.clear();
       mapOverlays.add(0, myLocationOverlay);
       mapOverlays.add(1, itemizedoverlay);

       //Set focus for the map
       mapController.animateTo(point); 
       mapController.setCenter(point);
   }
    
	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}
	
	private void SetListServicesMapOverLay(){		
		 for (int i = 0; i < service_data.size(); i++)
		 {
			 Log.i("GoogleMapActivity-ServiceName",service_data.get(i).getName());
			ServiceDTO serviceDTO = service_data.get(i);
			int lat = (int) (serviceDTO.getLatitude() * 1E6);
			int lon = (int) (serviceDTO.getLongitude() * 1E6);
			
			IconTextDrawable drawable = new IconTextDrawable(this, MyDictionary.dictionary.get(serviceDTO.getCategoryId()), Utils.StringToMultiLineString(serviceDTO.getName(), 25));
			MyItemizedOverlay itemizedoverlay = new MyItemizedOverlay(drawable, this);
			GeoPoint point = new GeoPoint(lat,lon);			
	 	    String info = "";
	 	    if (serviceDTO.getAddress()!=null)
	 	    	if (serviceDTO.getAddress().length() != 0)
	 	    		info += Html.fromHtml("Address: " + serviceDTO.getAddress()).toString();
	 	    if (serviceDTO.getPhoneNumber()!=null)
	 	    	if (serviceDTO.getPhoneNumber().replace(" ", "").length() != 0)
	 	    		info += Html.fromHtml("<br/>Phone: " + serviceDTO.getPhoneNumber()).toString();
			OverlayItem overlayitem = new OverlayItem(point, serviceDTO.getName(), info);
			itemizedoverlay.addOverlay(overlayitem);
			
			mapOverlays.add(itemizedoverlay);
		}
	}
	
	private void clearListServicesInMapOverlay(){
		Log.i("GoogleMapActivity","Start_clearListServicesInMapOverlay");
		Log.i("GoogleMapActivity",String.valueOf(mapOverlays.size()));
		
		Overlay temp = mapOverlays.get(1);
		//MyItemizedOverlay temp = (MyItemizedOverlay) mapOverlays.get(0);
		Log.i("GoogleMapActivity","remove");
		//mapOverlays.removeAll(mapOverlays);
		mapOverlays.clear();
		Log.i("GoogleMapActivity","add");
		//mapOverlays.add(temp);
		mapOverlays.add(0, myLocationOverlay); //Add google compass
		mapOverlays.add(1, temp); //Add hand point: your location
		Log.i("GoogleMapActivity","End_clearListServicesInMapOverlay");
	}
	

	private void RefreshMap(){
		mapView.invalidate();
		Log.i("GoogleMapActivity","RefreshMap");
	}
	
	private void clearButton()
	{
		button_OK_Change_Your_Location.setVisibility(View.INVISIBLE);
		button_OK_Driving_Directions.setVisibility(View.INVISIBLE);
		button_Get_Directions.setVisibility(View.INVISIBLE);		
	}
	 
	 @Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		 
		 //Inflate with submenu
		 //MenuInflater inflater = new MenuInflater(this);

	     switch (state_of_googlemap) {
	     case Constants.STATE_GOOGLEMAP_DISPLAY_ONE_SERVICE:
	    	 menu.clear();
	    	 menu.add(1, optionsItemSelected_GetDirection, 1, "Get Directions");
	    	 break;
	     case Constants.STATE_GOOGLEMAP_SET_SERVICE_LOCATION:
	    	 menu.clear();
	    	 break;
	     case Constants.STATE_GOOGLEMAP_DISPLAY_LIST_SERVICE:
		     MenuInflater inflater = getMenuInflater();
		     inflater.inflate(R.menu.google_map_menu, menu);
	    	 break;
	     default:
	    	 break;
		}
		return super.onCreateOptionsMenu(menu);
	}

	 @Override
	 public boolean onOptionsItemSelected(MenuItem item){
		 // Handle item selection
		 switch (item.getItemId()) {
		 
		 case R.id.category_googlemap_activity:
		 {
			 this.clearButton();
			 this.RefreshMap();
			 return true;
		 }
		 case R.id.services:{
			 category = 0;
			 this.getListServiceWithCategoryAndDistance(category, distance_min, distance_max);
			 clearListServicesInMapOverlay();
			 this.SetListServicesMapOverLay();
			 item.setChecked(true);
			 this.RefreshMap();
			 return true;
		 }
		 case R.id.hotel:{
			 category = 1;
			 this.getListServiceWithCategoryAndDistance(category, distance_min, distance_max);
			 clearListServicesInMapOverlay();
			 this.SetListServicesMapOverLay();
			 item.setChecked(true);
			 this.RefreshMap();
			 return true;
		 }
		 case R.id.restaurant:{
			 category = 2;
			 this.getListServiceWithCategoryAndDistance(category, distance_min, distance_max);
			 clearListServicesInMapOverlay();
			 this.SetListServicesMapOverLay();
			 item.setChecked(true);
			 this.RefreshMap();
			 return true;
		 }
		 case R.id.atm:{
			 category = 3;
			 this.getListServiceWithCategoryAndDistance(category, distance_min, distance_max);
			 clearListServicesInMapOverlay();
			 this.SetListServicesMapOverLay();
			 item.setChecked(true);
			 this.RefreshMap();
			 return true;
		 }
		 case R.id.hospital:{
			 category = 4;
			 this.getListServiceWithCategoryAndDistance(category, distance_min, distance_max);
			 clearListServicesInMapOverlay();
			 this.SetListServicesMapOverLay();
			 item.setChecked(true);
			 this.RefreshMap();
			 return true;
		 }
		 case R.id.bookstore:{
			 category = 5;
			 this.getListServiceWithCategoryAndDistance(category, distance_min, distance_max);
			 clearListServicesInMapOverlay();
			 this.SetListServicesMapOverLay();
			 item.setChecked(true);
			 this.RefreshMap();
			 return true;
		 }
		 case R.id.karaoke:{
			 category = 6;
			 this.getListServiceWithCategoryAndDistance(category, distance_min, distance_max);
			 clearListServicesInMapOverlay();
			 this.SetListServicesMapOverLay();
			 item.setChecked(true);
			 this.RefreshMap();
			 return true;
		 }
		 case R.id.school:{
			 category = 7;
			 this.getListServiceWithCategoryAndDistance(category, distance_min, distance_max);
			 clearListServicesInMapOverlay();
			 this.SetListServicesMapOverLay();
			 item.setChecked(true);
			 this.RefreshMap();
			 return true;
		 }
		 case R.id.your_location:{
			 this.clearButton();
			 this.RefreshMap();
//			 int lat = (int) (curLocation.getLatitude() * 1E6);
//			 int lng = (int) (curLocation.getLongitude() * 1E6);
			 GeoPoint point = new GeoPoint((int)(OrientationHelper.getCurLat()*1E6), (int)(OrientationHelper.getCurLon()*1E6));
			 mapController.animateTo(point); 
			 mapController.setCenter(point);
			 return true;
		 }
		 case R.id.change_your_location:{
			 this.clearButton();
			 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);;
			 Editor editor = prefs.edit();
			 editor.putBoolean(Constants.autoUpdateLocation, false);
			 editor.commit();  			 
			 bool_autoUpdateLocation = false;
			 
			 GeoPoint point = new GeoPoint((int)(OrientationHelper.getCurLat()*1E6), (int)(OrientationHelper.getCurLon()*1E6));
			 mapController.animateTo(point); 
			 mapController.setCenter(point);
			 MyItemizedOverlay my = (MyItemizedOverlay)mapOverlays.get(1);
			 my.SetDragAndDrop(true);
			 mapOverlays.set(1, my);
			 button_OK_Change_Your_Location.setVisibility(View.VISIBLE);
			 Toast.makeText(this.getApplicationContext(), "Drag and drop the hand point to change your location", Toast.LENGTH_LONG).show();
			 this.clearListServicesInMapOverlay();
			 this.RefreshMap();
			 return true;
		 }
		 case R.id.clear:{
			 clearListServicesInMapOverlay();
			 this.clearButton();
			 this.RefreshMap();
			 return true;
		 }
		 
		 case R.id.distance_googlemap_activity:
		 {
			 this.clearButton();
			 this.RefreshMap();
			 return true;
		 }
		 
		 case R.id.d100m:{
			 clearListServicesInMapOverlay();
			 distance_min = 0;
			 distance_max = 100;
			 this.getListServiceWithCategoryAndDistance(category, distance_min, distance_max); 
			 this.SetListServicesMapOverLay();
			 item.setChecked(true);
			 this.RefreshMap();
			 return true;
		 }
		 case R.id.d200m:{
			 clearListServicesInMapOverlay();
			 distance_min = 100;
			 distance_max = 200;
			 this.getListServiceWithCategoryAndDistance(category, distance_min, distance_max);  
			 this.SetListServicesMapOverLay();
			 item.setChecked(true);
			 this.RefreshMap();
			 return true;
		 }
		 case R.id.d500m:{
			 clearListServicesInMapOverlay();
			 distance_min = 200;
			 distance_max = 500;
			 this.getListServiceWithCategoryAndDistance(category, distance_min, distance_max); 	 
			 this.SetListServicesMapOverLay();
			 item.setChecked(true);
			 this.RefreshMap();
			 return true;
		 }
		 case R.id.d1000m:{
			 clearListServicesInMapOverlay();
			 distance_min = 500;
			 distance_max = 1000;
			 this.getListServiceWithCategoryAndDistance(category, distance_min, distance_max);  
			 this.SetListServicesMapOverLay();
			 item.setChecked(true);
			 this.RefreshMap();
			 return true;
		 }
		 case R.id.d2000m:{
			 clearListServicesInMapOverlay();
			 distance_min = 1000;
			 distance_max = 2000;
			 this.getListServiceWithCategoryAndDistance(category, distance_min, distance_max);  
			 this.SetListServicesMapOverLay();
			 item.setChecked(true);
			 this.RefreshMap();
			 return true;
		 }
		 case R.id.d5000m:{
			 clearListServicesInMapOverlay();
			 distance_min = 2000;
			 distance_max = 5000;
			 this.getListServiceWithCategoryAndDistance(category, distance_min, distance_max);  
			 this.SetListServicesMapOverLay();
			 item.setChecked(true);
			 this.RefreshMap();
			 return true;
		 }
		 
		 case R.id.driving_directions:
		 {			
			 this.clearButton();
			 this.clearListServicesInMapOverlay();
			 this.RefreshMap();
			 
			 DisplayMetrics metrics = new DisplayMetrics();
			 getWindowManager().getDefaultDisplay().getMetrics(metrics);

			 GeoPoint a_Point = mapView.getProjection().fromPixels(metrics.widthPixels/3, metrics.heightPixels/3);
			 GeoPoint b_Point = mapView.getProjection().fromPixels(metrics.widthPixels*2/3, metrics.heightPixels*2/3);
			
			 Drawable A_drawable = GoogleMapActivity.this.getResources().getDrawable(R.drawable.marker_green_start);
	         MyItemizedOverlay a_itemizedoverlay = new MyItemizedOverlay(A_drawable, GoogleMapActivity.this, (ImageView)findViewById(R.id.imageview_a_point), true);
	        
			 Drawable B_drawable = GoogleMapActivity.this.getResources().getDrawable(R.drawable.marker_green_end);
	         MyItemizedOverlay b_itemizedoverlay = new MyItemizedOverlay(B_drawable, GoogleMapActivity.this, (ImageView)findViewById(R.id.imageview_b_point), true);

	         OverlayItem a_overlayitem = new OverlayItem(a_Point, "Start", "Start point");
	         OverlayItem b_overlayitem = new OverlayItem(b_Point, "End", "End point");
	        
	         a_itemizedoverlay.addOverlay(a_overlayitem);
	         b_itemizedoverlay.addOverlay(b_overlayitem);
			
	         mapOverlays.add(a_itemizedoverlay);
	         mapOverlays.add(b_itemizedoverlay);
		        
			 button_OK_Driving_Directions.setVisibility(View.VISIBLE);
			 Toast.makeText(this.getApplicationContext(), "Drag and drop A point and B point.", Toast.LENGTH_LONG).show();
			 
			 return true;
		 }
		 
		 case optionsItemSelected_GetDirection:
		 {
    		 AlertDialog.Builder dialog = new AlertDialog.Builder(GoogleMapActivity.this);
    		 dialog.setTitle("Directions");
    		 dialog.setMessage(directions_message);
    		 dialog.show();
    		 return true;
		 }
		 
		 case R.id.online_friend_lists:{
			 this.clearButton();
			 this.clearListServicesInMapOverlay();
			 this.RefreshMap();
			 if (NetworkHelper.isNetworkAvailable(GoogleMapActivity.this))
			 {
				 ArrayList<UserDTO> onlineFriends;
				 ChatServiceHelper chat = new ChatServiceHelper();
				 onlineFriends = chat.getOnlineFriends();
				 if (onlineFriends != null)
				 {
					 int zoomLat = 0;
					 int zoomLon = 0;
					 float distance_max = 0;
					 for (int i = 0; i < onlineFriends.size(); i++)
					 {
						
						UserDTO userDTO = onlineFriends.get(i);
						int lat = (int) (userDTO.latitude * 1E6);
						int lon = (int) (userDTO.longtitude * 1E6);						
						
						int count = 0;
						if (lat != 1E6 || lon != 1E6)
						{
							count++;
							if (distance_max < OrientationHelper.CalculateDistanceBetweenTwoPoints(OrientationHelper.getCurLat(), OrientationHelper.getCurLon(), userDTO.latitude, userDTO.longtitude));
							{
								zoomLat = (int)(userDTO.latitude * 1E6);
								zoomLon = (int)(userDTO.longtitude * 1E6);								
							}
								
							IconTextDrawable drawable = new IconTextDrawable(this, R.drawable.face, Utils.StringToMultiLineString(userDTO.name, 25));
							MyItemizedOverlay itemizedoverlay = new MyItemizedOverlay(drawable, this);
							GeoPoint point = new GeoPoint(lat,lon);			
					 	    String info = "";
					 	    if (userDTO.name != null)
					 	    	info += Html.fromHtml("Name: " + userDTO.name).toString();
					 	    if (userDTO.email != null)
					 	    	info += Html.fromHtml("<br/>Email: " + userDTO.email).toString();
							OverlayItem overlayitem = new OverlayItem(point, userDTO.name, info);
							itemizedoverlay.addOverlay(overlayitem);
							
							mapOverlays.add(itemizedoverlay);
						}
						Toast.makeText(this.getApplicationContext(), "Online Friend: " + String.valueOf(count), Toast.LENGTH_LONG).show();
					 }
					 if (zoomLat != 0 || zoomLon !=0)
					 {
					        mapController.zoomToSpan(Math.abs((int)(OrientationHelper.getCurLat()*1E6) - zoomLat)*2, Math.abs((int)(OrientationHelper.getCurLon()*1E6)  - zoomLon)*2);
					        mapController.animateTo(new GeoPoint((int)(OrientationHelper.getCurLat()*1E6), (int)(OrientationHelper.getCurLon()*1E6)));
					 }
					 
				 }
				 else
				 {
					 Toast.makeText(this.getApplicationContext(), "No friend online.", Toast.LENGTH_LONG).show();
				 }
			 }
			 this.clearButton();
			 this.RefreshMap();
			 return true;
		 }
		 default:
			 return super.onOptionsItemSelected(item);
		 }    	
	 }
	 
	 @SuppressWarnings("unchecked")
	private void getListService()
	 {
		 //Database----------------------------------------------------------------
	         categoryDB = new CategoryDB(this);
	         categoryDB.open();
	         category_data = new ArrayList<CategoryDTO>();
	         category_data = categoryDB.getAllCategories();
	         categoryDB.close();
	         
	         itemDB = new ItemDB(this);
	         itemDB.open();
	         service_data_original = new ArrayList<ServiceDTO>();
	         service_data_original = itemDB.getAllServices();
	         itemDB.close();
	         service_data = new ArrayList<ServiceDTO>();
	         service_data = (ArrayList<ServiceDTO>) service_data_original.clone();
	     //------------------------------------------------------------------------
	 }
	 
	 private void getListServiceWithCategoryAndDistance(int _category, int _disntance_min, int _distance_max)
	 {
		 service_data.clear();
		 if (_category == 0)
		 {
			 for (int i = 0; i < service_data_original.size(); i++)
			 {
				 double distance =OrientationHelper.CalculateDistanceBetweenTwoPoints(OrientationHelper.getCurLon(), OrientationHelper.getCurLat(), service_data_original.get(i).getLongitude(), service_data_original.get(i).getLatitude()); 
				 if (_disntance_min <= distance && distance < _distance_max)
					 service_data.add(service_data_original.get(i));
			 }
		 }
		 else
		 {
			 for (int i = 0; i < service_data_original.size(); i++)
				 if (service_data_original.get(i).getCategoryId() == _category)
				 {
					 double distance =OrientationHelper.CalculateDistanceBetweenTwoPoints(OrientationHelper.getCurLon(), OrientationHelper.getCurLat(), service_data_original.get(i).getLongitude(), service_data_original.get(i).getLatitude()); 
					 if (_disntance_min <= distance && distance < _distance_max)
						 service_data.add(service_data_original.get(i));
				 }
		 }
	 }
	 
	 

	    private void updateOrientation(float[] values) {
	    	if (MainActivity.autoChangeScreen ==true && Math.abs(values[1]) > 70 && changeIntent == true) 
	    	{
	    		changeIntent = false;
				Intent myIntent = new Intent(GoogleMapActivity.this, MainActivity.class);
				myIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
				startActivity(myIntent);
	    	}
	    }
	    
	    private final SensorEventListener sensorEventListener = new SensorEventListener() {
			public void onSensorChanged(SensorEvent event) {
	    		boolean flag  = false;
	    		
	    		
	    		//Kiem tra su thay doi cua sensor ACCELEROMETER va MAGNETIC_FIELD
	    		switch(event.sensor.getType()){
	    		  case Sensor.TYPE_ACCELEROMETER:
	    		   for(int i =0; i < 3; i++){
	    		    aValues[i] = event.values[i];
	    		   }
	    		   flag = true;
	    		   break;
	    		  case Sensor.TYPE_MAGNETIC_FIELD:
	    		   for(int i =0; i < 3; i++){
	    		    mValues[i] = event.values[i];
	    		   }
	    		   flag = true;
	    		   break;
	    		  }

	    		if (flag == true)
	    		{

	    		   	float[] values = new float[3];
	    	    	float[] R = new float[9];
	    	        float[] outR = new float[9];
	    	        
	    	        //Lay Rotation Matrix => R
	    	        boolean success = SensorManager.getRotationMatrix(R, null, aValues, mValues);
	    	        
	    	        //Thay doi he truc khi quay thiet bi di dong
	    	        if (success)
	    	        {
	        	        String windoSrvc = Context.WINDOW_SERVICE;
	        	        WindowManager wm = ((WindowManager) getSystemService(windoSrvc));
	        	        Display display = wm.getDefaultDisplay();
	        	        int rotation = display.getRotation();
	        	        
	        	        int x_axis = SensorManager.AXIS_X; 
	        	        int y_axis = SensorManager.AXIS_Y;
	        	        switch (rotation) {
	        	        case (Surface.ROTATION_90): 
	        	        	x_axis = SensorManager.AXIS_Y; 
	        	        	y_axis = SensorManager.AXIS_MINUS_X; 
	        	        	break;
	        	        case (Surface.ROTATION_180): 
	        	        	y_axis = SensorManager.AXIS_MINUS_Y; 
	        	        	break;
	        	        case (Surface.ROTATION_270): 
	        	        	x_axis = SensorManager.AXIS_MINUS_Y; 
	        	        	y_axis = SensorManager.AXIS_X; 
	        	        	break;
	        	        default: break;
	        	        }

	        	        SensorManager.remapCoordinateSystem(R, x_axis, y_axis, outR);
	        	       
	        	
	// R = Rz * Rx * Ry        	        
	        	        double bank1, attitude1, heading1;
	      	        
	        	        if (outR[7]> 0.9) { //-Sin(Pitch) ~ 0.9
		        	        heading1 = Math.atan2(-outR[3],outR[0]);
		        	        attitude1 = -Math.PI/2;
		        	        bank1 = 0;
		        	        values[1] = (float)(attitude1/Math.PI*180);
		        	        values[2] = (float)(bank1/Math.PI*180);
		        	        values[0] = (float)(heading1/Math.PI*180);
	        	        }
	        	        else if (outR[7] < -0.9) { //-Sin(Pitch) ~ -0.9
	        	        	heading1 = Math.atan2(-outR[3],outR[0]);
		        	        attitude1 = Math.PI/2;
		        	        bank1 = 0;
		        	        values[1] = (float)(attitude1/Math.PI*180);
		        	        values[2] = (float)(bank1/Math.PI*180);
		        	        values[0] = (float)(heading1/Math.PI*180);
	        	        }
	        	        else
	        	        {      	    	
		        	        heading1 = Math.atan2(outR[1],outR[4]);
		        	        attitude1 = -Math.asin(outR[7]);
		        	        bank1 = Math.atan2(outR[6],outR[8]);   	        
		        	        values[0] = (float)(heading1/Math.PI*180);
		        	        values[1] = (float)(attitude1/Math.PI*180);
		        	        values[2] = (float)(bank1/Math.PI*180);    	    	
	        	        }
	        	        
	        	        //Kalman Filter
						kmYaw.update(values[0]);
						values[0] = (float)kmYaw.getX();
						kmPitch.update(values[1]); 
						values[1] = (float)kmPitch.getX();
						kmRoll.update(values[2]); 
						values[2] = (float)kmRoll.getX();	       	        
	        	     
						
	        	        //Update huong cua compass & yeu cau draw lai compass
	        	    	updateOrientation(values);
	    	        }     
	    		}
	    	}
	    	public void onAccuracyChanged(Sensor sensor, int accuracy) {}
	    };
	    @Override
	    protected void onResume()
	    {
		    super.onResume();
		  
		    myLocationOverlay.enableCompass();
		    
			SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);;
			bool_autoUpdateLocation = prefs.getBoolean(Constants.autoUpdateLocation, true);
			
		    
		    //changeIntent = true;
	    	if (isCompass == true)
	    	{
			    Sensor accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
			    Sensor magField = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
			    
			    sensorManager.registerListener(sensorEventListener, accelerometer, SensorManager.SENSOR_DELAY_FASTEST);
			    sensorManager.registerListener(sensorEventListener, magField, SensorManager.SENSOR_DELAY_FASTEST);
	    	}
	    }
	    
	    @Override
	    public void onPause() {
	      super.onPause();
	      
	      myLocationOverlay.disableCompass();
	    }  
	    
	    @Override
	    protected void onStop()
	    {
	    	if (isCompass == true)
	    	{
	    		sensorManager.unregisterListener(sensorEventListener);
	    		Log.i("Googlemap","UnregisterListener");
	    	}
	    	super.onStop();
	    }
	    
	    @Override
	    public void onBackPressed() {
	    	// TODO Auto-generated method stub
	    	super.onBackPressed();
	    	Log.i("Googlemap","onBackPressed");
	    	setResult(RESULT_OK);
	        finish();
	    }
	    
	    @Override
	    public void onConfigurationChanged(Configuration newConfig) {
	    	// TODO Auto-generated method stub
	    	super.onConfigurationChanged(newConfig);
	    }
	    
	//Mot class
	public class GeoUpdateHandler implements LocationListener {

		//------
		private Context mContext;
		public GeoUpdateHandler(Context context){
			mContext = context;
		}
		//------
		public void onLocationChanged(Location location) {
			if (bool_autoUpdateLocation == true)
			{
	//			curLocation = location;
				int lat = (int) (location.getLatitude() * 1E6);
				int lng = (int) (location.getLongitude() * 1E6);
				
				OrientationHelper.setCurLatLon(location.getLatitude(),location.getLongitude());
				GeoPoint point = new GeoPoint(lat, lng);
				
				RefreshMap();
				MyItemizedOverlay itemizedoverlay = new MyItemizedOverlay(drawable, mContext, (ImageView)findViewById(R.id.drag), false);
				OverlayItem overlayitem = new OverlayItem(point, "Notify", "You're here!");
		        itemizedoverlay.addOverlay(overlayitem);

		        mapOverlays.set(1, itemizedoverlay);
		        Log.i("Googlemap","Change location");
		        if(myLocationOverlay.isCompassEnabled() == false)
		        	myLocationOverlay.enableCompass();
			}
	        
		}
		
		
		
		public void onProviderDisabled(String provider) {
		}

		public void onProviderEnabled(String provider) {
			
		}

		public void onStatusChanged(String provider, int status, Bundle extras) {
		}		
		
	}
}
